package tr.gov.tubitak.bilgem.esya.certviewer;

import java.io.*;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.Provider;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateFactory;
import java.security.cert.CertificateParsingException;
import java.security.cert.X509Certificate;
import java.util.Date;

public class ECertUtil
{
    public static byte[] getDERCertDataFromFile(File file)
            throws CertificateParsingException, FileNotFoundException, IOException
    {
        /* Read the file data into a byte array */
        FileInputStream in = new FileInputStream(file);
        byte [] buffer = new byte[(int) (file.length())];
        in.read(buffer);
        in.close();

        /* check if this is pem base64 encoded data - if it is, translate it */
        if (ESecurity.isPEM(buffer))
        {
            //XXX <your code to handle unencrypted private keys here> XXX//

//System.out.println("\nparsing PEM data!!\n");

            byte[] pemData = ESecurity.convertFromPEMCertificate(buffer);
            if (pemData == null)
                throw new CertificateParsingException("Unable to parse PEM encoded cert - invalid PEM encoding.");

            buffer = pemData;
        }

        return buffer;
    }

    /**
     * Load an X509Certificate object from a specified file.  If this
     * function is able to load the certificate from the file, return
     * the object, otherwise, return <code>null</code>.
     *
     * - <i>Warning: may not correctly handle pem files - CB</i>
     *
     * @param fileName The name of the file containing the X.509 Certificate.
     * @return An <code>X509Certificate</code> object containing the
     * certificate, or <code>null</code>.
     */

// TODO: logging, and bubble exception properly to a level that can display them.


    public static X509Certificate loadX509Certificate (String fileName)
    {
        return loadX509Certificate(new File(fileName));

    }
    public static X509Certificate loadX509Certificate (File file)
    {
        try
        {
            FileInputStream inputStream = new FileInputStream (file);

            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            X509Certificate cert = (X509Certificate)cf.generateCertificate(inputStream);
            inputStream.close();

            return cert;
        }
        catch (Exception anyException)
        {
            anyException.printStackTrace ();
            return null;
        }
    }


    /**
     * Load certificate from byte array (DER)
     */
    public static X509Certificate loadX509Certificate (byte[] certdata) throws Exception {
        try
        {
            ByteArrayInputStream inputStream = new ByteArrayInputStream (certdata);

            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            Provider provider = cf.getProvider();
            X509Certificate cert = (X509Certificate)cf.generateCertificate(inputStream);
            inputStream.close();
            cf = null;
            inputStream=null;
            return cert;
        }
        catch (Exception e)
        {
            e.printStackTrace ();
            throw e;
        }
    }


    /**
     * Saving a DER encoded certificate to a directory.
     * Precondition: directory must be created before hand.
     */
    public static void saveCertToDisk(byte[] certBytes, String outputDir) throws Exception
    {
        X509Certificate cert = loadX509Certificate(certBytes);
        FileOutputStream fos = null;
        String fileName = outputDir + "/" + cert.getSubjectDN().getName() + "_" + new Date().getTime() + ".der";
        try
        {
            fos = new FileOutputStream(fileName);
        }
        catch (Exception ex)
        {
            System.out.println("Could not open " + fileName + " for saving cert, now use " +
                    (fileName = new Date().getTime() + ".der"));
            fos = new FileOutputStream(fileName);
        }

        fos.write(certBytes);
        fos.close();
    }
}